#include "sectmanagerpanel.h"
#include "createnodedialog.h"
#include "nodemanager/wnodemanager.h"

SectParamEditPanel::SectParamEditPanel(wxWindow* parent)
    : wxPanel(parent, wxID_ANY),
    mSectNode(NULL),
    m_SectTextEditFinished(false),
    m_RangeTextEditFinished(false),
    m_LastSectEditFinished(false),
    m_NextSectEditFinished(false),
    m_AccessRuleEditFinished(false)
{
    InitUI();
}

SectParamEditPanel::~SectParamEditPanel()
{

}

// 挂接道岔改变信号槽
void SectParamEditPanel::sig_ProcessItemChanged(SectManagerPanel *pSectManagerPanel)
{
    sig_item_change.connect(pSectManagerPanel,&SectManagerPanel::slot_ProcessItemChanged);
}

void SectParamEditPanel::InitUI()
{
    m_sectNameLabel = new wxStaticText(this, wxID_ANY, wxT("区段名称:"));
    m_sectNameText = new wxTextCtrl(this, wxID_ANY, "",
                                    wxDefaultPosition, wxDefaultSize,
                                    wxTE_PROCESS_ENTER);

    m_deviceidLabel = new wxStaticText(this, wxID_ANY, wxT("设备ID:"));
    m_deviceidText = new wxTextCtrl(this, wxID_ANY, "",
                                    wxDefaultPosition, wxDefaultSize,
                                    wxTE_PROCESS_ENTER);

    m_rangeLabel = new wxStaticText(this, wxID_ANY, wxT("区段范围:"));
    m_rangeText = new wxTextCtrl(this, wxID_ANY, "",
                                 wxDefaultPosition, wxDefaultSize,
                                 wxTE_READONLY);

    std::lock_guard<std::mutex> lock(*(WNodeManager::getSingleton().getSectMutex()));
    wxArrayString decsects;
    std::map<wxString,tagSectNode*> decallsects = WNodeManager::getSingleton().getAllSects();
    std::map<wxString,tagSectNode*>::iterator iter = decallsects.begin();
    for(;iter != decallsects.end();++iter)
    {
        decsects.push_back((*iter).first);
    }

    m_lastsectLabel = new wxStaticText(this, wxID_ANY, wxT("上一个区段:"));
    m_lastsectText = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
                                    decsects, wxTE_PROCESS_ENTER);

    m_nextsectLabel = new wxStaticText(this, wxID_ANY, wxT("下一个区段:"));
    m_nextsectText = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
                                    decsects, wxTE_PROCESS_ENTER);

    m_AccessRuleLabel = new wxStaticText(this, wxID_ANY, wxT("进出类型:"));
    m_AccessRuleText = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
                                      CreateChoiceArray({wxT("进"), wxT("出"),wxT("进出"),wxT("停靠"),wxT("无类型")}),
                                    wxCB_READONLY);

    // 布局
    wxFlexGridSizer* mainSizer = new wxFlexGridSizer(10, 2, 5, 5);
    mainSizer->AddGrowableCol(1);
    mainSizer->SetFlexibleDirection(wxBOTH);

    mainSizer->Add(m_sectNameLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
    mainSizer->Add(m_sectNameText, 1, wxEXPAND | wxALL, 5);

    mainSizer->Add(m_deviceidLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
    mainSizer->Add(m_deviceidText, 1, wxEXPAND | wxALL, 5);

    mainSizer->Add(m_rangeLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
    mainSizer->Add(m_rangeText, 1, wxEXPAND | wxALL, 5);

    mainSizer->Add(m_lastsectLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
    mainSizer->Add(m_lastsectText, 1, wxEXPAND | wxALL, 5);

    mainSizer->Add(m_nextsectLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
    mainSizer->Add(m_nextsectText, 1, wxEXPAND | wxALL, 5);

    mainSizer->Add(m_AccessRuleLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
    mainSizer->Add(m_AccessRuleText, 1, wxEXPAND | wxALL, 5);

    SetSizerAndFit(mainSizer);

    m_sectNameText->Bind(wxEVT_TEXT, &SectParamEditPanel::OnSectNameTextChanged, this);
    m_sectNameText->Bind(wxEVT_KILL_FOCUS, &SectParamEditPanel::OnSectNameTextKillFocus, this);
    m_sectNameText->Bind(wxEVT_TEXT_ENTER, &SectParamEditPanel::OnSectNameTextEnter, this);
    m_lastsectText->Bind(wxEVT_TEXT, &SectParamEditPanel::OnLastSectChanged, this);
    m_lastsectText->Bind(wxEVT_KILL_FOCUS, &SectParamEditPanel::OnLastSectKillFocus, this);
    m_lastsectText->Bind(wxEVT_TEXT_ENTER, &SectParamEditPanel::OnLastSectEnter, this);
    m_nextsectText->Bind(wxEVT_TEXT, &SectParamEditPanel::OnNextSectChanged, this);
    m_nextsectText->Bind(wxEVT_KILL_FOCUS, &SectParamEditPanel::OnNextSectKillFocus, this);
    m_nextsectText->Bind(wxEVT_TEXT_ENTER, &SectParamEditPanel::OnNextSectEnter, this);
    m_deviceidText->Bind(wxEVT_TEXT, &SectParamEditPanel::OnDeviceIDTextChanged, this);
    m_deviceidText->Bind(wxEVT_KILL_FOCUS, &SectParamEditPanel::OnDeviceIDTextKillFocus, this);
    m_deviceidText->Bind(wxEVT_TEXT_ENTER, &SectParamEditPanel::OnDeviceIDTextEnter, this);

    m_lastsectText->Bind(wxEVT_COMBOBOX, &SectParamEditPanel::OnLastSectComboBoxSelected, this);
    m_nextsectText->Bind(wxEVT_COMBOBOX, &SectParamEditPanel::OnNextSectComboBoxSelected, this);
    m_AccessRuleText->Bind(wxEVT_COMBOBOX, &SectParamEditPanel::OnAccessRuleComboBoxSelected, this);
}

void SectParamEditPanel::OnLastSectComboBoxSelected(wxCommandEvent& event)
{
    sig_item_change.emitt(mSectNode,3,m_lastChangedData["lastsects"],m_lastsectText->GetValue());
    m_lastChangedData["lastsects"]=m_lastsectText->GetValue();
    event.Skip();
}

void SectParamEditPanel::OnNextSectComboBoxSelected(wxCommandEvent& event)
{
    sig_item_change.emitt(mSectNode,4,m_lastChangedData["nextsects"],m_nextsectText->GetValue());
    m_lastChangedData["nextsects"]=m_nextsectText->GetValue();
    event.Skip();
}

void SectParamEditPanel::OnAccessRuleComboBoxSelected(wxCommandEvent& event)
{
    sig_item_change.emitt(mSectNode,5,m_lastChangedData["accessrule"],m_AccessRuleText->GetValue());
    m_lastChangedData["accessrule"]=m_AccessRuleText->GetValue();
    event.Skip();
}


void SectParamEditPanel::OnDeviceIDTextChanged(wxCommandEvent& event)
{
    m_deviceidEditFinished = true;
}

void SectParamEditPanel::OnDeviceIDTextKillFocus(wxFocusEvent& event)
{
    if(m_deviceidEditFinished)
    {
        sig_item_change.emitt(mSectNode,1,m_lastChangedData["deviceid"],m_deviceidText->GetValue());
        m_lastChangedData["deviceid"]=m_deviceidText->GetValue();
        m_deviceidEditFinished = false;
    }
    event.Skip();
}

void SectParamEditPanel::OnDeviceIDTextEnter(wxCommandEvent& event)
{
    if(m_deviceidEditFinished)
    {
        sig_item_change.emitt(mSectNode,1,m_lastChangedData["deviceid"],m_deviceidText->GetValue());
        m_lastChangedData["deviceid"]=m_deviceidText->GetValue();
        m_deviceidEditFinished = false;
    }
    event.Skip();
}

void SectParamEditPanel::OnSectNameTextChanged(wxCommandEvent& event)
{
    m_SectTextEditFinished = true;
}

void SectParamEditPanel::OnSectNameTextKillFocus(wxFocusEvent& event)
{
    if(m_SectTextEditFinished)
    {
        sig_item_change.emitt(mSectNode,0,m_lastChangedData["sect_name"],m_sectNameText->GetValue());
        m_lastChangedData["sect_name"]=m_sectNameText->GetValue();
        m_SectTextEditFinished = false;
    }
    event.Skip();
}

void SectParamEditPanel::OnSectNameTextEnter(wxCommandEvent& event)
{
    if(m_SectTextEditFinished)
    {
        sig_item_change.emitt(mSectNode,0,m_lastChangedData["sect_name"],m_sectNameText->GetValue());
        m_lastChangedData["sect_name"]=m_sectNameText->GetValue();
        m_SectTextEditFinished = false;
    }
    event.Skip();
}

void SectParamEditPanel::OnLastSectChanged(wxCommandEvent& event)
{
    m_LastSectEditFinished = true;
}

void SectParamEditPanel::OnLastSectKillFocus(wxFocusEvent& event)
{
    if(m_LastSectEditFinished)
    {
        sig_item_change.emitt(mSectNode,3,m_lastChangedData["lastsects"],m_lastsectText->GetValue());
        m_lastChangedData["lastsects"]=m_lastsectText->GetValue();
        m_LastSectEditFinished = false;
    }
    event.Skip();
}

void SectParamEditPanel::OnLastSectEnter(wxCommandEvent& event)
{
    if(m_LastSectEditFinished)
    {
        sig_item_change.emitt(mSectNode,3,m_lastChangedData["lastsects"],m_lastsectText->GetValue());
        m_lastChangedData["lastsects"]=m_lastsectText->GetValue();
        m_LastSectEditFinished = false;
    }
    event.Skip();
}

void SectParamEditPanel::OnNextSectChanged(wxCommandEvent& event)
{
    m_NextSectEditFinished = true;
}

void SectParamEditPanel::OnNextSectKillFocus(wxFocusEvent& event)
{
    if(m_NextSectEditFinished)
    {
        sig_item_change.emitt(mSectNode,4,m_lastChangedData["nextsects"],m_nextsectText->GetValue());
        m_lastChangedData["nextsects"]=m_nextsectText->GetValue();
        m_NextSectEditFinished = false;
    }
    event.Skip();
}

void SectParamEditPanel::OnNextSectEnter(wxCommandEvent& event)
{
    if(m_NextSectEditFinished)
    {
        sig_item_change.emitt(mSectNode,4,m_lastChangedData["nextsects"],m_nextsectText->GetValue());
        m_lastChangedData["nextsects"]=m_nextsectText->GetValue();
        m_NextSectEditFinished = false;
    }
    event.Skip();
}

// 重置所有参数
void SectParamEditPanel::resetAllData(void)
{
    m_sectNameText->SetValue("");
    m_lastsectText->SetValue("");
    m_nextsectText->SetValue("");
    m_rangeText->SetValue("");
    m_deviceidText->SetValue("");
    m_AccessRuleText->SetValue("");
}

// 获取所有参数数据
std::map<wxString, wxString> SectParamEditPanel::GetData() const
{
    std::map<wxString, wxString> data;
    data["sect_name"] = m_sectNameText->GetValue();
    data["deviceid"] = m_deviceidText->GetValue();
    data["sect_range"] = m_rangeText->GetValue();
    data["lastsects"] = m_lastsectText->GetValue();
    data["nextsects"] = m_nextsectText->GetValue();
    data["accessrule"] = m_AccessRuleText->GetValue();

    return data;
}

// 设置参数数据
void SectParamEditPanel::SetData(const std::map<wxString, wxString>& data)
{
    m_lastChangedData = data;

    if (data.count("sect_name")) m_sectNameText->SetValue(data.at("sect_name"));
    if (data.count("deviceid")) m_deviceidText->SetValue(data.at("deviceid"));
    if (data.count("sect_range")) m_rangeText->SetValue(data.at("sect_range"));
    if (data.count("accessrule")) m_AccessRuleText->SetValue(data.at("accessrule"));
    if (data.count("lastsects"))
    {
        m_lastsectText->Clear();
        std::map<wxString,tagSectNode*> decallsects = WNodeManager::getSingleton().getAllSects();
        std::map<wxString,tagSectNode*>::iterator iter = decallsects.begin();
        for(;iter != decallsects.end();++iter)
        {
            m_lastsectText->Append((*iter).first);
        }

        m_lastsectText->SetValue(data.at("lastsects"));
    }
    else
    {
        m_lastsectText->Clear();
    }
    if (data.count("nextsects"))
    {
        m_nextsectText->Clear();
        std::map<wxString,tagSectNode*> decallsects = WNodeManager::getSingleton().getAllSects();
        std::map<wxString,tagSectNode*>::iterator iter = decallsects.begin();
        for(;iter != decallsects.end();++iter)
        {
            m_nextsectText->Append((*iter).first);
        }

        m_nextsectText->SetValue(data.at("nextsects"));
    }
    else
    {
        m_nextsectText->Clear();
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SectRangePanel::SectRangePanel(wxWindow *parent)
    : wxPanel(parent),
    mSectNode(NULL)
{
    // 创建主垂直布局
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

    // 创建DataViewCtrl
    m_dvc = new wxDataViewCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE);

    // 创建数据存储
    m_store = new wxDataViewListStore();
    m_dvc->AssociateModel(m_store);

    mainSizer->Add(m_dvc, 1, wxEXPAND);

    SetSizer(mainSizer);

    wxArrayString choices;
    choices.Add(wxT("定位"));
    choices.Add(wxT("反位"));

    wxDataViewColumn* column = new wxDataViewColumn(
        "区段范围",
        new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_LEFT),
        0,
        70);
    m_dvc->AppendColumn(column);

    wxArrayString choices1;

    std::map<wxString,WBaseNode*> allnodes = WNodeManager::getSingleton().getAllNodes();
    std::map<wxString,WBaseNode*>::iterator iternode = allnodes.begin();
    for(;iternode != allnodes.end();++iternode)
        choices1.Add((*iternode).second->getName());

    m_choicescolumnStart = new wxDataViewColumn(
        wxT("开始结点"),
        new wxDataViewChoiceRenderer(choices1, wxDATAVIEW_CELL_EDITABLE, wxALIGN_LEFT),
        1,
        70);
    m_dvc->AppendColumn(m_choicescolumnStart);

    m_choicescolumnEnd = new wxDataViewColumn(
        wxT("结束结点"),
        new wxDataViewChoiceRenderer(choices1, wxDATAVIEW_CELL_EDITABLE, wxALIGN_LEFT),
        2,
        70);
    m_dvc->AppendColumn(m_choicescolumnEnd);

    this->Bind(wxEVT_DATAVIEW_ITEM_EDITING_DONE, &SectRangePanel::OnEditingDone, this, m_dvc->GetId());
    m_dvc->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &SectRangePanel::OnRightClick, this);
}

SectRangePanel::~SectRangePanel()
{

}

// 挂接道岔改变信号槽
void SectRangePanel::sig_ProcessRangeItemChanged(SectManagerPanel *pSectManagerPanel)
{
    sig_range_change.connect(pSectManagerPanel,&SectManagerPanel::slot_ProcessItemRangeChanged);
}

// 重置所有参数
void SectRangePanel::resetAllData(void)
{
    m_store->DeleteAllItems();
}

void SectRangePanel::OnRightClick(wxDataViewEvent& event)
{
    if(mSectNode == NULL)
        return;

    wxDataViewItem item = event.GetItem();
    if (item.IsOk())
    {
        wxVariant decvalue;
        m_dvc->GetModel()->GetValue(decvalue, item, 0);

        // 创建并显示菜单
        wxMenu menu;
        menu.Append(IDD_PARAMEDIT_DELETENODE,
                    wxString::Format(wxT("删除 '%s'"),decvalue.GetString()));
        menu.Bind(wxEVT_MENU, &SectRangePanel::OnDeleteRange, this, IDD_PARAMEDIT_DELETENODE);

        m_dvc->PopupMenu(&menu, event.GetPosition());
    }
    else
    {
        // 创建并显示菜单
        wxMenu menu;
        menu.Append(IDD_PARAMEDIT_ADD_MOUNTNODE,wxT("添加区段范围"));

        menu.Bind(wxEVT_MENU, &SectRangePanel::OnAddNewRange, this, IDD_PARAMEDIT_ADD_MOUNTNODE);

        m_dvc->PopupMenu(&menu, event.GetPosition());
    }

    event.Skip();
}

void SectRangePanel::OnDeleteRange(wxCommandEvent& event)
{
    wxMessageDialog dialog(
        this,
        wxT("您是否要删除当前区段范围?"),
        wxT("警告"),
        wxYES_NO | wxICON_QUESTION | wxICON_WARNING
        );

    if (dialog.ShowModal() == wxID_YES && mSectNode != NULL)
    {
        wxVariant decvalue;
        m_dvc->GetModel()->GetValue(decvalue, m_dvc->GetSelection(), 0);

        SwitchState pSwitchState = (decvalue.GetString() == wxT("定位") ? SwitchState::POSITIVE : SwitchState::NEGATIVE);

        std::map<int,wxVector<WBaseNode*>> sectnodes = mSectNode->nodes;
        std::map<int,wxVector<WBaseNode*>>::iterator iter = sectnodes.find((int)pSwitchState);
        if(iter != sectnodes.end())
            sectnodes.erase(iter);

        m_store->DeleteItem(m_store->GetRow(m_dvc->GetSelection()));
    }
}

void SectRangePanel::OnAddNewRange(wxCommandEvent& event)
{
    wxVector<wxVariant> decdata;
    decdata.push_back(wxT("定位"));
    decdata.push_back("");
    decdata.push_back("");

    this->addData(decdata);
}

void SectRangePanel::OnEditingDone(wxDataViewEvent& event)
{
    event.Skip();

    wxDataViewItem item = event.GetItem();
    int col = event.GetColumn();

    if (event.IsEditCancelled())
        return;

    wxVariant oldvalue;
    m_dvc->GetModel()->GetValue(oldvalue, item, col);
    wxVariant newvalue = event.GetValue();

    if(oldvalue.GetString() == newvalue.GetString() ||
        newvalue.GetString() == "" ||
        mSectNode == NULL)
        return;

    /*if(col == 0)
    {
        SwitchState pSwitchState = (oldvalue.GetString() == "定位" ? SwitchState::POSITIVE : SwitchState::NEGATIVE);
        std::map<int,wxVector<WBaseNode*>> sectnodes = mSectNode->nodes;
        std::map<int,wxVector<WBaseNode*>>::iterator iter = sectnodes.find((int)pSwitchState);
        if(iter != sectnodes.end())
            sectnodes.erase(iter);

        pSwitchState = (newvalue.GetString() == "定位" ? SwitchState::POSITIVE : SwitchState::NEGATIVE);

        wxVariant startnode,endnode;
        m_dvc->GetModel()->GetValue(startnode, item, 1);
        m_dvc->GetModel()->GetValue(endnode, item, 2);

        wxVector<WBaseNode*> decVector;
        wxVector<tagSLRouteNode> decroute = WNodeManager::getSingleton().getRoute(startnode.GetString(),endnode.GetString());

        for(int ii=0;ii<decroute.size();ii++)
        {
            decVector.push_back(decroute[ii].node);
        }

        if(!decVector.empty())
            mSectNode->nodes[(int)pSwitchState] = decVector;
    }
    else */
    if(col == 2)
    {
        wxVariant sectType;
        m_dvc->GetModel()->GetValue(sectType, item, 0);

        SwitchState pSwitchState = (sectType.GetString() == wxT("定位") ? SwitchState::POSITIVE : SwitchState::NEGATIVE);

        wxVariant startnode;
        m_dvc->GetModel()->GetValue(startnode, item, 1);
        //m_dvc->GetModel()->GetValue(endnode, item, 2);

        if(startnode.GetString() != newvalue.GetString())
        {
            wxVector<WBaseNode*> decVector;
            wxVector<tagSLRouteNode> decroute = WNodeManager::getSingleton().getRoute(startnode.GetString(),newvalue.GetString());

            for(int ii=0;ii<decroute.size();ii++)
            {
                decVector.push_back(decroute[ii].node);
            }

            if(!decVector.empty())
            {
                mSectNode->nodes[(int)pSwitchState] = decVector;

                wxString decString;
                std::map<int,wxVector<WBaseNode*>> sectnodes = mSectNode->nodes;
                std::map<int,wxVector<WBaseNode*>>::iterator iter = sectnodes.begin();
                for(;iter != sectnodes.end();++iter)
                {
                    if((*iter).second.size() >= 2)
                        decString += wxString::Format(wxT("%s-%s;"),
                                                      (*iter).second[0]->getName(),
                                                      (*iter).second[(*iter).second.size()-1]->getName());
                }

                if(!decString.empty())
                    sig_range_change.emitt("",decString.Mid(0,decString.size()-1));
            }
        }
    }
}

void SectRangePanel::clearAllData(void)
{
    m_store->DeleteAllItems();
}

// 重新加载所有的结点
void SectRangePanel::reloadAllNodes(void)
{
    m_dvc->DeleteColumn(m_choicescolumnStart);
    m_dvc->DeleteColumn(m_choicescolumnEnd);

    wxArrayString choices1;

    std::map<wxString,WBaseNode*> allnodes = WNodeManager::getSingleton().getAllNodes();
    std::map<wxString,WBaseNode*>::iterator iternode = allnodes.begin();
    for(;iternode != allnodes.end();++iternode)
        choices1.Add((*iternode).second->getName());

    m_choicescolumnStart = new wxDataViewColumn(
        wxT("开始结点"),
        new wxDataViewChoiceRenderer(choices1, wxDATAVIEW_CELL_EDITABLE, wxALIGN_LEFT),
        1,
        70);
    m_dvc->InsertColumn(1,m_choicescolumnStart);

    m_choicescolumnEnd = new wxDataViewColumn(
        wxT("结束结点"),
        new wxDataViewChoiceRenderer(choices1, wxDATAVIEW_CELL_EDITABLE, wxALIGN_LEFT),
        2,
        70);
    m_dvc->InsertColumn(2,m_choicescolumnEnd);

    m_dvc->Refresh();
}

void SectRangePanel::addData(const wxVector<wxVariant> data)
{
    m_store->AppendItem(data);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SectManagerPanel::SectManagerPanel(wxWindow *parent)
    : wxPanel(parent)
{
    // 创建主垂直布局
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* panelSizer = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* mountSizer = new wxBoxSizer(wxVERTICAL);

    m_SectParamEditPanel = new SectParamEditPanel(this);
    m_SectRangePanel = new SectRangePanel(this);

    m_SectParamEditPanel->sig_ProcessItemChanged(this);
    m_SectRangePanel->sig_ProcessRangeItemChanged(this);

    // 创建DataViewCtrl
    m_dvc = new wxDataViewCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE);

    // 创建数据存储
    m_store = new wxDataViewListStore();
    m_dvc->AssociateModel(m_store);

    mountSizer->Add(m_SectParamEditPanel, 1, wxEXPAND);
    mountSizer->Add(m_SectRangePanel, 1, wxEXPAND);

    panelSizer->Add(m_dvc, 3, wxEXPAND);
    panelSizer->Add(mountSizer, 1, wxEXPAND);

    mainSizer->Add(panelSizer, 1, wxEXPAND);

    SetSizer(mainSizer);

    m_dvc->AppendTextColumn(wxT("区段名称"), m_dvc->GetColumnCount(), wxDATAVIEW_CELL_ACTIVATABLE, 100);
    m_dvc->AppendTextColumn(wxT("设备ID"), m_dvc->GetColumnCount(), wxDATAVIEW_CELL_ACTIVATABLE, 70);
    m_dvc->AppendTextColumn(wxT("区段范围"), m_dvc->GetColumnCount(), wxDATAVIEW_CELL_ACTIVATABLE, 170);
    m_dvc->AppendTextColumn(wxT("上一个区段"), m_dvc->GetColumnCount(), wxDATAVIEW_CELL_ACTIVATABLE, 120);
    m_dvc->AppendTextColumn(wxT("下一个区段"), m_dvc->GetColumnCount(), wxDATAVIEW_CELL_ACTIVATABLE, 120);
    m_dvc->AppendTextColumn(wxT("进出类型"), m_dvc->GetColumnCount(), wxDATAVIEW_CELL_ACTIVATABLE, 80);

    m_dvc->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &SectManagerPanel::OnRightClick, this);
    m_dvc->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &SectManagerPanel::OnSelectionChanged, this);
}

SectManagerPanel::~SectManagerPanel()
{

}

void SectManagerPanel::OnSelectionChanged(wxDataViewEvent& event)
{
    // 获取当前选中的项目
    wxDataViewItem selectedItem = m_dvc->GetSelection();

    if (selectedItem.IsOk()) {
        // 获取模型
        wxDataViewModel* model = m_dvc->GetModel();

        std::map<wxString, wxString> data;

        // 获取第一列的值
        wxVariant value;
        model->GetValue(value, selectedItem, 0);
        data["sect_name"] = value.GetString();
        model->GetValue(value, selectedItem, 1);
        data["deviceid"] = value.GetString();
        model->GetValue(value, selectedItem, 2);
        data["sect_range"] = value.GetString();
        model->GetValue(value, selectedItem, 3);
        data["lastsects"] = value.GetString();
        model->GetValue(value, selectedItem, 4);
        data["nextsects"] = value.GetString();
        model->GetValue(value, selectedItem, 5);
        data["accessrule"] = value.GetString();

        m_SectParamEditPanel->SetData(data);

        tagSectNode* pSectNode = WNodeManager::getSingleton().getSect(data["sect_name"]);
        if(pSectNode != NULL)
        {
            m_SectParamEditPanel->setSectNode(pSectNode);
            m_SectRangePanel->setSectNode(pSectNode);
            m_SectRangePanel->reloadAllNodes();

            m_SectRangePanel->clearAllData();

            std::map<int,wxVector<WBaseNode*>> sectnodes = pSectNode->nodes;
            std::map<int,wxVector<WBaseNode*>>::iterator iter = sectnodes.begin();
            for(;iter != sectnodes.end();++iter)
            {
                if((*iter).second.size() >= 2)
                {
                    wxVector<wxVariant> decdata;
                    decdata.push_back((*iter).first == 0 ? wxT("定位") : wxT("反位"));
                    decdata.push_back((*iter).second[0]->getName());
                    decdata.push_back((*iter).second[(*iter).second.size()-1]->getName());

                    m_SectRangePanel->addData(decdata);
                }
            }
        }
    }
}

void SectManagerPanel::OnRightClick(wxDataViewEvent& event)
{
    wxDataViewItem item = event.GetItem();
    if (item.IsOk())
    {
        // 获取第一列的值
        wxVariant value;
        m_dvc->GetModel()->GetValue(value, item, 0);

        // 创建并显示菜单
        wxMenu menu;
        menu.Append(IDD_PARAMEDIT_DELETENODE,
                    wxString::Format(wxT("删除区段 '%s'"),value.GetString()));
        menu.Bind(wxEVT_MENU, &SectManagerPanel::OnDeleteSect, this, IDD_PARAMEDIT_DELETENODE);

        m_dvc->PopupMenu(&menu, event.GetPosition());
    }
    else
    {
        // 创建并显示菜单
        wxMenu menu;
        menu.Append(IDD_PARAMEDIT_ADD_MOUNTNODE,wxT("添加区段"));

        menu.Bind(wxEVT_MENU, &SectManagerPanel::OnAddNewSect, this, IDD_PARAMEDIT_ADD_MOUNTNODE);

        m_dvc->PopupMenu(&menu, event.GetPosition());
    }

    event.Skip();
}

void SectManagerPanel::OnDeleteSect(wxCommandEvent& event)
{
    // 弹出确认对话框
    wxMessageDialog dialog(
        this,
        wxT("您是否要删除当前区段?"),
        wxT("警告"),
        wxYES_NO | wxICON_QUESTION | wxICON_WARNING
        );

    if (dialog.ShowModal() == wxID_YES)
    {
        // 获取第一列的值
        wxVariant value;
        m_dvc->GetModel()->GetValue(value, m_dvc->GetSelection(), 0);

        if(WNodeManager::getSingleton().deleteSectByName(value.GetString()))
        {
            m_store->DeleteItem(m_store->GetRow(m_dvc->GetSelection()));
            m_SectParamEditPanel->resetAllData();
            m_SectRangePanel->resetAllData();
        }
    }

    event.Skip();
}

void SectManagerPanel::OnAddNewSect(wxCommandEvent& event)
{
    CreateNodeDialog dlg(this, wxT("创建区段"));
    if (dlg.ShowModal() == wxID_OK)
    {
        wxString nodeName = dlg.GetNodeName();

        // 检测创建的区段是否存在
        if(WNodeManager::getSingleton().getSect(nodeName) != NULL)
        {
            wxMessageBox(wxString::Format(wxT("'%s'已经存在系统中，无法添加!"),nodeName),
                         wxT("警告"),
                         wxOK | wxICON_WARNING, this);
            return;
        }

        tagSectNode *newsect = new tagSectNode();
        newsect->sectname = nodeName;

        if(WNodeManager::getSingleton().addSect(newsect))
        {
            this->addSect(newsect);
        }
    }
}

void SectManagerPanel::slot_ProcessItemRangeChanged(wxString oldparams,wxString newparams)
{
    if(newparams == "" ||
        m_SectParamEditPanel->getRange() == newparams)
        return;

    m_SectParamEditPanel->setRange(newparams);

    wxDataViewItem selected = m_dvc->GetSelection();

    if (selected.IsOk())
    {
        const wxDataViewColumn* column = m_dvc->GetColumn(2);

        m_store->SetValue(wxVariant(newparams), selected, column->GetModelColumn());
        m_store->ItemChanged(selected);
    }
}

void SectManagerPanel::slot_ProcessItemChanged(tagSectNode *pSectNode,int itemindex,wxString olddata,wxString newdata)
{
    if(pSectNode == NULL || olddata == newdata)
        return;

    // 获取当前选中项
    wxDataViewItem selected = m_dvc->GetSelection();

    if (selected.IsOk())
    {
        const wxDataViewColumn* column = m_dvc->GetColumn(itemindex);

        m_store->SetValue(wxVariant(newdata), selected, column->GetModelColumn());
        m_store->ItemChanged(selected);
    }

    switch(itemindex)
    {
    case 0:
    {
        if(WNodeManager::getSingleton().updateSectByName(olddata,newdata))
        {

        }
    }
        break;
    case 1:
    {
        int deviceid = 0;
        newdata.ToInt(&deviceid);

        pSectNode->deviceID = deviceid;
    }
        break;
    case 3:
    {
        pSectNode->lastsects = SplitString(newdata,";");
    }
        break;
    case 4:
    {
        pSectNode->nextsects = SplitString(newdata,";");
    }
        break;
    case 5:
    {
        if(newdata == wxT("进"))
            pSectNode->accessrule = SectAccessRule::ACCESS_ENTER;
        else if(newdata == wxT("出"))
            pSectNode->accessrule = SectAccessRule::ACCESS_EXIT;
        else if(newdata == wxT("进出"))
            pSectNode->accessrule = SectAccessRule::ACCESS_ENTERANDEXIT;
        else if(newdata == wxT("停靠"))
            pSectNode->accessrule = SectAccessRule::ACCESS_BERTH;
        else
            pSectNode->accessrule = SectAccessRule::ACCESS_NULL;
    }
    break;
    default:
        break;
    }
}

void SectManagerPanel::addSect(const tagSectNode* sectnode)
{
    if(sectnode == NULL) return;

    wxVector<wxVariant> decdata;
    decdata.push_back(sectnode->sectname);
    decdata.push_back(wxString::Format("%d",sectnode->deviceID));

    std::map<int,wxVector<WBaseNode*>> decnodes = sectnode->nodes;

    wxString rangeStr;
    std::map<int,wxVector<WBaseNode*>>::iterator iter = decnodes.begin();
    for(;iter != decnodes.end();++iter)
    {
        if((*iter).second.size() < 2)
            continue;

        rangeStr += wxString::Format(wxT("%s-%s;"),
                                     (*iter).second[0]->getName(),
                                     (*iter).second[(*iter).second.size()-1]->getName());
    }
    decdata.push_back(rangeStr.empty() ? "" : rangeStr.Mid(0,rangeStr.length()-1));

    wxString lastsectStr;
    for(int i=0;i<sectnode->lastsects.size();i++)
    {
        lastsectStr += wxString::Format(wxT("%s;"),sectnode->lastsects[i]);
    }
    decdata.push_back(lastsectStr.empty() ? "" : lastsectStr.Mid(0,lastsectStr.length()-1));

    wxString nextsectStr;
    for(int i=0;i<sectnode->nextsects.size();i++)
    {
        nextsectStr += wxString::Format(wxT("%s;"),sectnode->nextsects[i]);
    }
    decdata.push_back(nextsectStr.empty() ? "" : nextsectStr.Mid(0,nextsectStr.length()-1));

    wxString accessrulestring = wxT("无类型");
    switch(sectnode->accessrule)
    {
    case SectAccessRule::ACCESS_ENTER:
        accessrulestring = wxT("进");
        break;
    case SectAccessRule::ACCESS_EXIT:
        accessrulestring = wxT("出");
        break;
    case SectAccessRule::ACCESS_ENTERANDEXIT:
        accessrulestring = wxT("进出");
        break;
    case SectAccessRule::ACCESS_BERTH:
        accessrulestring = wxT("停靠");
        break;
    default:
        break;
    }
    decdata.push_back(accessrulestring);

    this->addData(decdata);
}

void SectManagerPanel::addData(const wxVector<wxVariant> data)
{
    m_store->AppendItem(data);
}
